package wei.qiang.ye.dynamicdatasourceshardingjdbc01.service;

import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import wei.qiang.ye.dynamicdatasourceshardingjdbc01.domain.OrderDO;
import wei.qiang.ye.dynamicdatasourceshardingjdbc01.domain.UserDO;
import wei.qiang.ye.dynamicdatasourceshardingjdbc01.mapper.OrderMapper;
import wei.qiang.ye.dynamicdatasourceshardingjdbc01.mapper.UserMapper;

@Service
public class OrderService {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private UserMapper userMapper;

    private OrderService self() {
        return (OrderService) AopContext.currentProxy();
    }

    public void method01() {
        // 查询订单
        OrderDO order = orderMapper.selectById(1);
        System.out.println(order);
        // 查询用户
        UserDO user = userMapper.selectById(1);
        System.out.println(user);
    }

    /**
     * 项目配置
     * 分库分表中间件返回的 Connection 返回的实际是动态的 DynamicRoutingConnection ，它管理了整个请求（逻辑）过程中，
     * 使用的所有的 Connection ，而最终执行 SQL 的时候，DynamicRoutingConnection 会解析 SQL ，
     * 获得表对应的真正的 Connection 执行 SQL 操作。
     */
    @Transactional
    public void method02() {
        // 查询订单
        OrderDO order = orderMapper.selectById(1);
        System.out.println(order);
        // 查询用户
        UserDO user = userMapper.selectById(1);
        System.out.println(user);
    }

    public void method03() {
        // 查询订单
        self().method03_1();
        // 查询用户
        self().method03_2();
    }

    @Transactional
    public void method03_1() {
        OrderDO order = orderMapper.selectById(1);
        System.out.println(order);
    }

    @Transactional
    public void method03_2() {
        UserDO user = userMapper.selectById(1);
        System.out.println(user);
    }

    public void method04() {
        // 查询订单
        self().method04_1();
        // 查询用户
        self().method04_2();
    }


    @Transactional
    public void method04_1() {
        OrderDO order = orderMapper.selectById(1);
        System.out.println(order);
    }

    @Transactional
    public void method04_2() {
        UserDO user = userMapper.selectById(1);
        System.out.println(user);
    }

    @Transactional
    public void method05() {
        // 查询订单
        OrderDO order = orderMapper.selectById(1);
        System.out.println(order);
        // 查询用户
        self().method05_2();
    }

    /**
     * 事务传播级别是 Propagation.REQUIRES_NEW 。此时，在执行 #method05_2() 方法之前，
     * TransactionInterceptor 会将原事务挂起，暂时性的将原事务信息和当前线程解绑。
     * 所以，在执行 #method052() 方法前，又可以执行一轮事务的逻辑。
     * 在执行 #method052() 方法完成后，会将原事务恢复，重新将原事务信息和当前线程绑定。
     */
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void method05_2() {
        UserDO user = userMapper.selectById(1);
        System.out.println(user);
    }
}
